/**
 * @file ice_cream_control.c
 * @brief 冰淇淋机硬件控制接口实现
 * @details 调用底层设备控制函数，实现上层统一接口的功能映射
 */
#include "ice_cream_control.h"
#include "ice_cream_driver.h"
#include "axis_ctrl.h"
#include "sys_pub.h"
// 最大原点回归尝试脉冲数（防止无限循环）
#define MAX_HOMING_PULSES 10000

static void x_set_pulse(uint8_t level) {
   IO_CONTROL(X_PUL_PIN,level);
}

static void x_set_dir(uint8_t level) 
{
   IO_CONTROL(X_DIR_PIN,level);
}

static uint8_t x_read_origin(void) {
    return IO_READ(X0_PIN);
}

static void z_set_pulse(uint8_t level)
 {
    IO_CONTROL(Z_PUL_PIN,level);
}

static void z_set_dir(uint8_t level)
 {
    IO_CONTROL(Z_DIR_PIN,level);
}

static uint8_t z_read_origin(void) {
    return IO_READ(X1_PIN);
}

// -------------------------- 4. X/Z轴硬件操作实例（axis_hw_ops 结构体初始化） --------------------------
// X轴硬件操作集合（函数指针绑定）
const axis_hw_ops x_axis_hw = {
    .set_pulse = x_set_pulse,    // 绑定X轴脉冲控制函数
    .set_dir = x_set_dir,        // 绑定X轴方向控制函数
    .read_origin = x_read_origin // 绑定X轴原点读取函数
};

// Z轴硬件操作集合（函数指针绑定）
const axis_hw_ops z_axis_hw = {
    .set_pulse = z_set_pulse,
    .set_dir = z_set_dir,
    .read_origin = z_read_origin
};

// -------------------------- 5. X/Z轴原点回归参数配置（axis_homing_cfg 结构体初始化） --------------------------
// X轴原点回归参数（根据X轴行程/精度需求调整）
const axis_homing_cfg x_homing_cfg = {
    .max_homing_steps = 10000,   // 最大回归步数（防无限循环）
    .escape_steps = 50,          // 脱离原点步数（避免传感器误触发）
    .fine_adjust_steps = 20,     // 精调退步数（提升原点定位精度）
    .timeout_ms = 50000           // 回归超时时间（5秒，超时判定失败）
};

// Z轴原点回归参数（Z轴行程通常较短，参数可差异化）
const axis_homing_cfg z_homing_cfg = {
    .max_homing_steps = 8000,    // Z轴最大回归步数（小于X轴）
    .escape_steps = 30,          // Z轴脱离步数（小于X轴）
    .fine_adjust_steps = 15,     // Z轴精调步数（小于X轴）
    .timeout_ms = 40000           // Z轴回归超时（4秒）
};

// -------------------------- 6. X/Z轴初始化函数（对外提供，简化使用） --------------------------
/**
 * @brief X/Z轴统一初始化
 * 作用：初始化硬件IO + 绑定轴控制接口 + 设置默认参数
 */
void axis_ctrl_init_all(void) {

    // 2. 初始化X轴（轴ID=AXIS_X，绑定硬件操作+回归参数，默认脉冲间隔5ms）
    axis_init(AXIS_X, &x_axis_hw, &x_homing_cfg, 5);

    // 3. 初始化Z轴（轴ID=AXIS_Z，绑定硬件操作+回归参数，默认脉冲间隔8ms）
    // Z轴负载通常更轻，默认速度较慢（间隔更大）以保证稳定性
    axis_init(AXIS_Z, &z_axis_hw, &z_homing_cfg, 8);
}

// -------------------------- 静态全局变量（状态管理） --------------------------
// 设备就绪状态标志
static bool s_device_ready = false;
// 轴原点回归完成标志
static bool s_x_homed = false;
static bool s_z_homed = false;
// 系统时间（由底层中断更新）
extern volatile uint32_t system_time_ms;  // 底层接口中定义的系统时间变量
//落杯时间tick
static uint32_t s_cup_drop_start_time = 0;
//当前落杯状态
static bool s_cup_drop_state = false;
// -------------------------- 硬件初始化实现 --------------------------
void ice_control_init(void) {
    // 1. 调用底层初始化函数
    ice_cream_control_init();  // 底层：初始化所有轴、执行器、传感器
    axis_ctrl_init_all();
    // 2. 初始化状态变量
    s_device_ready = true;
    s_x_homed = false;
    s_z_homed = false;
  
    // 3. 停止所有执行器，确保初始状态安全
    ice_cream_control_stop_all();
}

bool ice_cream_control_is_ready(void) {
    return s_device_ready;
}
/**
 * @brief 启动X轴步进电机运动
 * @param dir 运动方向：1=正方向，0=反方向
 * @param steps 运动步数
 * @param step_delay 步间延时（微秒）
 * @return 启动成功返回true，失败（如正在运动）返回false
 */
bool start_x_axis_movement(int dir,uint32_t steps) {

    if(dir)
    {
       return axis_forward_steps(AXIS_X,steps);
    }else
    {
      return  axis_backward_steps(AXIS_X,steps);
    }    
}

/**
 * @brief 启动Z轴步进电机运动
 * @param dir 运动方向：1=正方向，0=反方向
 * @param steps 运动步数
 * @param step_delay 步间延时（微秒）
 * @return 启动成功返回true，失败（如正在运动）返回false
 */
bool start_z_axis_movement(int dir,uint32_t steps) {
 

    if(dir)
    {
      return  axis_forward_steps(AXIS_Z,steps);
    }else
    {
      return  axis_backward_steps(AXIS_Z,steps);
    }
}


/**
 * @brief 启动X轴步进电机运动
 * @param dir 运动方向：1=正方向，0=反方向
 * @param steps 运动步数
 * @param step_delay 步间延时（微秒）
 * @return 启动成功返回true，失败（如正在运动）返回false
 */
bool start_x_axis_moveto(uint32_t target_pos) 
{
    return axis_move_to(AXIS_X,target_pos) ;
}

/**
 * @brief 启动Z轴步进电机运动
 * @param dir 运动方向：1=正方向，0=反方向
 * @param steps 运动步数
 * @param step_delay 步间延时（微秒）
 * @return 启动成功返回true，失败（如正在运动）返回false
 */
bool start_z_axis_moveto(uint32_t target_pos) 
{
  return axis_move_to(AXIS_Z,target_pos) ;
}


/**
 * @brief 检查X轴是否正在运动
 * @return 正在运动返回true，否则返回false
 */
bool is_x_axis_moving(void) {
    return (bool)(axis_is_move_complete(AXIS_X)==0);
}

/**
 * @brief 检查Z轴是否正在运动
 * @return 正在运动返回true，否则返回false
 */
bool is_z_axis_moving(void) {
   return (bool)(axis_is_move_complete(AXIS_Z)==0);
}

/**
 * @brief 启动X轴原点回归
 * @return 启动成功返回true，失败（如正在回归）返回false
 */
bool start_x_axis_homing(void) {
 return axis_start_homing(AXIS_X);
}

/**
 * @brief 启动Z轴原点回归
 * @return 启动成功返回true，失败（如正在回归）返回false
 */
bool start_z_axis_homing(void) {
 
    return axis_start_homing(AXIS_Z);
}

/**
 * @brief 获取X轴原点回归状态
 * @return 0=未开始，1=正在回归，2=完成，3=失败
 */
uint8_t get_x_axis_homing_state(void)
{
    axis_state state = axis_get_state(AXIS_X);
    // 完成状态：空闲、回归完成
     if (state == AXIS_STATE_HOMING_OK)return 2;
     if (state == AXIS_STATE_HOMING_ERR)return 3;
    if (state == AXIS_STATE_HOMING_STEP1)return 0;
    if (state == AXIS_STATE_HOMING_STEP2)return 1;
    if (state == AXIS_STATE_HOMING_STEP3)return 1;
    if (state == AXIS_STATE_HOMING_STEP4)return 1;
    return 3;
}

/**
 * @brief 获取Z轴原点回归状态
 * @return 0=未开始，1=正在回归，2=完成，3=失败
 */
uint8_t get_z_axis_homing_state(void)
{
        axis_state state = axis_get_state(AXIS_Z);
    // 完成状态：空闲、回归完成
     if (state == AXIS_STATE_HOMING_OK)return 2;
     if (state == AXIS_STATE_HOMING_ERR)return 3;
    if (state == AXIS_STATE_HOMING_STEP1)return 0;
    if (state == AXIS_STATE_HOMING_STEP2)return 1;
    if (state == AXIS_STATE_HOMING_STEP3)return 1;
    if (state == AXIS_STATE_HOMING_STEP4)return 1;
    return 3;
}

// -------------------------- 轴控制实现（X/Z双轴） --------------------------
bool axis_xz_move_to(AxisPosition target) {
    // 检查轴是否正忙
    if (is_x_axis_moving() || is_z_axis_moving()) {
        return false;
    }
    
    bool x_ok=start_x_axis_moveto( target.x_pos) ;
    bool z_ok=start_z_axis_moveto( target.z_pos) ;
    
    return (bool)(x_ok && z_ok);
}

bool axis_xz_is_moving(void) {
    // 调用底层接口，检查X/Z轴是否正在运动
    return (bool)(is_x_axis_moving() || is_z_axis_moving());
}

AxisPosition axis_xz_get_current_pos(void) {
    // 调用底层接口，获取当前位置并封装为AxisPosition
    AxisPosition pos;
    pos.x_pos = get_x_axis_position();
    pos.z_pos = get_z_axis_position();
    return pos;
}

bool axis_xz_homing(void) {
    // 检查是否正在回归
    if (get_x_axis_homing_state() == 1 || get_z_axis_homing_state() == 1) {
        return false;
    }
    
    // 启动双轴原点回归（底层接口）
    bool x_ok = start_x_axis_homing();
    bool z_ok = start_z_axis_homing();
    // 更新回归状态标志
    if (x_ok && z_ok) {
        s_x_homed = false;
        s_z_homed = false;
    }
    
    return (bool)(x_ok && z_ok);
}

bool axis_xz_is_homed(void) {
    // 检查底层回归状态，更新本地标志
    s_x_homed = (bool)(get_x_axis_homing_state() == 2);  // 2=回归完成
    s_z_homed = (bool)(get_z_axis_homing_state() == 2);
    return (bool)(s_x_homed && s_z_homed);
}
/**
 * @brief 获取X轴当前位置
 * @return X轴相对原点的位置（脉冲数）
 */
int32_t get_x_axis_position(void) {
      return axis_get_current_pos(AXIS_X);
}

/**
 * @brief 获取Z轴当前位置
 * @return Z轴相对原点的位置（脉冲数）
 */
int32_t get_z_axis_position(void) {
    return axis_get_current_pos(AXIS_Z);
}

// -------------------------- 杯子控制实现 --------------------------
bool cup_drop(void) {
    // 调用底层落杯电机控制，持续1秒（1000ms）
    //通过系统时间戳 持续1秒落杯控制

    if(s_cup_drop_state==0)
    {
        control_cup_drop_motor(1);
        s_cup_drop_start_time = system_get_time_ms();
        s_cup_drop_state = 1;
        return true;
    }
    else if(s_cup_drop_state==1)
    {
        if(system_get_time_ms()-s_cup_drop_start_time>1000)
        {
            control_cup_drop_motor(0);
            s_cup_drop_state=0;
        }
    }

   
    return false;  // 简化处理，实际可根据底层返回值判断
}

bool cup_is_present(void) {
    // 调用底层杯子检测传感器接口
    return (read_cup_detection() == 1);  // 1=检测到杯子
}

// -------------------------- 奶浆控制实现 --------------------------
bool milk_dispense_start(void) {
    // 启动主电机（挤奶浆），持续运行（duration=0）
    control_main_motor(1);
    // 启动提升电机上升（打开奶浆出料口），持续运行
    control_lifting_motor_up(1);
    return true;
}

bool milk_dispense_stop(void) {
    // 停止主电机
    control_main_motor(0);
    // 停止提升电机（确保出料口关闭）
    control_lifting_motor_up(0);
    control_lifting_motor_down(0);
    return true;
}

// -------------------------- 果酱控制实现 --------------------------
bool jam_dispense_start(uint8_t type) {
    // 校验果酱类型
    if (type < 1 || type > 3) {
        return false;
    }
    
    // 根据类型调用对应底层接口，持续运行（duration=0，由上层控制停止）

       control_jam(type, 1);
   
    return true;
}

bool jam_dispense_stop(uint8_t type) {
    if ( type > 3) {
        return false;
    }
    
    // 停止对应果酱电机
   control_jam(type, 0); 
  
    return true;
}

// -------------------------- 顶料控制实现 --------------------------
bool topping_dispense_start(uint8_t type) {
    if ( type > 2) {
        return false;
    }
    
    // 启动对应顶料电机，持续运行

     control_topping(type,1);


    return true;
}

bool topping_dispense_stop(uint8_t type) {
    if ( type > 2) {
        return false;
    }
    // 停止对应顶料电机
    control_topping(type, 0); 
    return true;
}

// -------------------------- 门控制实现 --------------------------
bool door_open(void) {
    // 调用底层门电机控制，开门2秒（确保门完全打开）
    control_door_motor(1);  // 1=开门，持续2000ms
    return true;
}

bool door_close(void) {
    // 关门2秒
    control_door_motor(0);  // 0=关门，持续2000ms
    return true;
}

bool door_is_open(void) {
    // 简化处理：假设门电机运行完成后即为对应状态（实际可增加门位置传感器）
    return (bool)(read_gripper_switch() == 1); 
}

// -------------------------- 取餐检测实现 --------------------------
bool takeaway_is_detected(void) {
    // 调用底层对射传感器+夹手开关，双重确认取餐
    uint8_t photo = read_photoelectric_signal();  // 1=遮挡，0=无遮挡
    uint8_t gripper = read_gripper_switch();      // 1=闭合，0=断开
    return (bool)(photo == 0 && gripper == 0);  // 无遮挡+夹手断开=取餐完成
}

// -------------------------- 系统辅助实现 --------------------------
uint32_t system_get_time_ms(void) {
    // 调用底层系统时间接口
    return system_time_ms;
}

void ice_cream_control_stop_all(void) {
    // 1. 停止轴运动
    start_x_axis_movement(0, 0);  // 停止X轴
    start_z_axis_movement(0, 0);  // 停止Z轴
    
    // 2. 停止所有执行器
    control_topping(0, 0);
    control_topping(1, 0);
    control_topping(2, 0);
    control_jam(0, 0);
    control_jam(1, 0);
    control_jam(2, 0);
    control_cup_drop_motor(0);
    control_expansion_pump(0);
    control_main_press(0);
    control_main_motor(0);
    control_precool_solenoid(0);
    control_refrigeration_solenoid(0);
    control_heating_solenoid(0);
    control_sterilizing_lamp(0);
    control_lifting_motor_up(0);
    control_lifting_motor_down(0);
    control_door_motor(0);
}